
function Vue(options) {
    this.$el = options.el;
    this.$options = options;
    this.$data = options.data();
    proxy(this.$data, this);
    observe(this.$data);
    new Compile(this.$el, this);
}

function proxy(data, vm) {
    if (isPlainObj) {
        Object.keys(data).forEach(key => {
            Object.defineProperty(vm, key, {
                get() {
                    return data[key];
                },
                set(newVal) {
                    data[key] = newVal
                },
            })
        })
    }
}

function observe(data) {
    if (Array.isArray(data)) {
        observeArray(data)
    } else if (isPlainObj) {
        Object.keys(data).forEach(key => {
            defineReactive(data, key, data[key]);
        })
    }
}

function defineReactive(obj, key, val) {
    if (isPlainObj(val)) {
        observe(val)
    }
    Object.defineProperty(obj, key, {
        get() {
            return val;
        },
        set(newVal) {
            if (newVal === val) {
                return;
            }
            val = newVal;
        },

    })
}

function isPlainObj(obj) {
    Object.prototype.toString.call(obj) === '[object, Object]';
}